## Welcome to GCCSDK GCC 4.7.4 Release 2 for RISC OS

If you have received this copy of GCC from a CD of fetched your copy from the Internet yourself some time ago, then it is likely there is a more up-to-date version obtainable from http://gccsdk.riscos.info/ which is also the homepage of this RISC OS GCC port.

### 1. Introduction

This is the RISC OS port of GCC (GNU Compiler Collection) and supporting binaries allowing you to start developing RISC OS applications and modules straight away. So you get a compiler for one or more languages, an linker, an assembler, a RISC OS module header and veneer generator, the UnixLib C runtime library and headers and stubs for the SharedCLibrary module (as found in the RISC OS ROMs).

This GCC port itself and the code produced using this GCC version is targeted and tested for RISC OS 4 (26-bit and 32-bit version), RISC OS 5 (32-bit version) and RISC OS 6 (26-bit and 32-bit version).

The RISC OS GNU Compiler Collection consists of a generic front end program `gcc' that provides a consistent interface to the compilers themselves. Currently compilers are supported for the C and C++ languages. Later releases of GCCSDK might have support for Ada, Fortran, Java, Pascal and/or Objective C/C++ but this will be largely dependant on available GCCSDK developer resources, interest and of course that all technical issues can be reasonably solved.

The following is a short introduction to GCC. It does not provide an introduction to programming, for that you will have to get a text book on the language you are interested in.

#### 1.1. Installation

To install GCC, copy the contents of !GCC onto your hard disc. Other compilers can be installed by copying the contents of their archives into the same directory as where you install GCC - RISC OS will automatically combine the !GCC directories together. Running !GCC will setup Run$Path to automatically search for the compiler tools.

As compilers are installed, sub-directories named according to the language they support will be placed within !GCC.docs. These sub-directories will contain specific information for the language compiler, including its usage and environment requirements.

This completes installation, and GCC may be used simply by typing 'gcc' at the CLI prompt. In order to verify which version of 'gcc' you are using, specify the --version switch:

       *gcc --version

#### 1.2. Simple compilations

The instructions below are generic and the ideas presented can be applied to all GNU compilers. The usage of C source files is merely for example purposes.

Source files are stored in the standard ASCII text format and kept in a directory that is relevant for the language of your program. For example, C programs are stored in directory 'c', C++ programs are stored in 'cc', assembler files in 's' and CMunge/CMHG files in 'cmhg'.

When specifying those source files for the compile, assembler or linker, it is recommended to use the 'my_c_program.c' syntax instead of the RISC OS file syntax 'c.my_c_program'.

For simple use, all that is needed is to set up a command line prompt and ensure there is enough free memory to run the compiler (details of memory requirements vary between compilers and can be found in the specific compiler documentation).

To compile a C program just type:

       *gcc hellow.c -o hellow

This will compile, assemble and link the source 'c.hellow' in one go to produce an ELF executable (filetype &E1F) called 'hellow'. An ELF executable can make use of static libraries and/or shared libraries (e.g. the UnixLib runtime library). By default, the shared libraries will be used (use link switch -static if you want static libraries to be used).

ELF executables need support of a loader module in order to be usable under RISC OS and this is provided by the '!SharedLibs' application which contains the SOManager RISC OS module. This means also that when ELF executables are distributed to users, they also need to have access to '!SharedLibs' application in order to be able to run the ELF based program.

It is possible to convert an ELF executable into a standalone AIF binary when the ELF executable is linked only using static libraries (i.e. when -static link switch has been used). This removes the need to distribute the '!SharedLibs' application together with the produced program but of course defeats the point of using shared libraries. This is done by running:

       *elf2aif hellow

When distributing ELF executables you probably want to strip the ELF executables first as well as this will reduce program size by removing all non-essential information. This is done by adding the switch '-Wl,-s':

       *gcc hellow.c -Wl,-s -o hellow

It is possible to compile several sources at one go, mixing C sources in the same program, using a command line of:

       *gcc file1.c file2.c file3.c file4.c -o myprogram

Again, this will compile, assemble and link all the sources to produce the ELF 'myprogram' executable.

To compile to the object form, use the -c switch. i.e.

       *gcc -c file.c

or

       *gcc -c file.c -o file.o

will compile and assemble 'c.file' to 'o.file'.

Support has been provided for both RISC OS and UNIX format filenames and we recommend to use the UNIX format style as this is more cross-platform compatible. For example (note in particular the last):

UNIX format (preferred) | RISC OS format
`../include/stdio.h` | `^.include.h.stdio`
`/work/gcc/hello.c` | `$.work.gcc.c.hello`
`stdlib.h` | `h.stdlib`
`tree.def` | `tree/def`

For further examples of compilation procedures, please look at `Examples' inside !GCC.

#### 1.3. More advanced compilations

##### 1.3.1. SharedCLibrary

By default UnixLib is used as runtime library. When it is important to use RISC OS' SharedCLibrary, at the expense of a much reduced API, you can do that by specifying the switch -mlibscl at compile and link time. The linker will produce an Absolute (filetype &FF8) file having an AIF header straight away instead of producing an ELF executable (filetype &E1F):

       *gcc -mlibscl -o file.o -c file.c
       *gcc -mlibscl -o mybinary file.o

##### 1.3.2. RISC OS module support

When C based modules are to be created, you can either have no runtime library or only the SharedCLibrary as runtime library. UnixLib is not suitable as a runtime library for modules. When you do not use SharedCLibrary in your module you're on your own implementing all your memory management, I/O, etc. (when needed) yourself (possibly using RISC OS' or third party modules' SWIs).

CMunge is used to create a RISC OS module header and the necessary setup code for each of the user required module entries, like initialisation, finalisation, service calls, command implementations etc. It can also be used to create veneer code acting as glue code for RISC OS callbacks into your C coded module.

At runtime the module will automatically get a private workspace holding internal state data (currently 3 words) but also all non-constant global variables used in your code. Initial non-zero non-constant global variables are stored in the module code itself and those get copied at startup in the module's private workspace where they can change during runtime. Initial zero global variables are not part of the module code but get a place in the private workspace as well. Constant global variables remain in the module and are not copied to the private workspace.

###### 1.3.2.1. CMunge

The requirements for CMunge are formulated in a .cmhg file which gets parsed by 'cmunge' to create an ELF object file and a header file. The generated header file contains all C prototypes of the user supplied routines used by the routines in the generated ELF object file.

Typically this is done by:

      *cmunge -tgcc -32bit -d modheader.h module.cmhg
      *cmunge -tgcc -32bit -o modheader.o module.cmhg

The generated modheader.h header file is included by all C code implementing the C functions specified in given .cmhg file.

See CMunge documentation for more information.

###### 1.3.2.2. Module support with SharedCLibrary

For all C compilations and final linking the switch -mmodule needs to be specified. For compiling this is required to make sure that global data can be properly relocated at runtime. For linking this will make sure the output is a valid RISC OS module containing the necessary relocations needed at start up time.

Specifying -mmodule implicitly specifies -mlibscl so it is not really necessary to specify it yourself. However if you want your build script (or Makefile) to be backwards compatible with GCCSDK 3.4 you have to specify -mlibscl as well as it was not done by default before.

In this example 'modheader.o' is already generated by CMunge before.

       *gcc -mlibscl -mmodule -O2 -c module.c -o module.o
       *gcc -mlibscl -mmodule module.o modheader.o -o mymodule

Module code executed in SVC or IRQ mode does not need to do any APCS stack checking (as the RISC OS R13 SVC and IRQ stacks are not chunked) so the switch -mmodule implicitly selects the -mno-apcs-stack-check switch as well. However some pieces of module code can also run in USR mode as e.g. module start code (hence, as application) so the -mapcs-stack-check switch is then explicitly needed to enforce chunk stack checking for those module object files containing code which is executed in USR mode.

###### 1.3.2.3. Module support without SharedCLibrary

Modules created without using SharedCLibrary have the advantage of not being dependent on the SharedCLibrary and have typically a smaller footprint. They are created by specifying the extra CMunge switch "-znoscl" (specifying not to generate code to interface with SharedCLibrary but generate code instead to setup the runtime stack itself) and by the extra linker switches "-nostdlib -lgcc" (specifying not to use any standard library, such as the SharedCLibrary, except the GCC library which contains helper routines possibly used by its generated code).

Note you can still include the standard headers (like stdbool.h, limits.h, stdlib.h, etc) to get some useful type definitions or constants but that does not mean you can use of any of the functions whose prototypes are defined there. If you want to avoid including any of the standard headers (for whatever reason), you can specify the extra compile switch "-nostdinc".

It might be that GCC generates code which contains memcmp, memset, memcpy and memmove calls. In such a case you need to provide those routines yourself (they are the same routines as the ones defined in standard C).

Calling RISC OS SWIs can be done by inline assembler calls, custom assembler routines or using a C library providing SWI level access like OSLib. Note that such libraries can not use the SharedCLibrary as well.

###### 1.3.2.4. Module resource data

Modules often have their data (Messages, Sprites, etc) stored in ResourceFS. mkresfs can be used to create a C file representing the intended ResourceFS data allowing easy (de)registration with ResourceFS. In GCCSDK 3.4 this functionality was covered with the 'resgen' program but as its code was very tightly AOF based, a new program (and approach) was chosen.

##### 1.3.3. Static UnixLib

When UnixLib is selected as runtime library, by default it will be the shared UnixLib library. It is possible to use the static UnixLib at link time by specifying the linker switch -static.

       *gcc -o file.o -c file.c
       *gcc -static -o mybinary file.o

##### 1.3.4. VFP

By default, GCC generates calls to functions within libgcc to handle floating point operations. This is called soft float and is somewhat faster than executing floating point instructions when those instructions are emulated by the floating point emulator. When compiling against Unixlib, GCC can also generate floating point code that targets the VFP instruction set (for instance, when writing code for the RaspberryPi). You can instruct GCC to use VFP like this:

       *gcc -o file.o -c file.c -mfpu=vfp
       *gcc -o mybinary file.o -mfpu=vfp

In this case, the binary is dynamically linked (no -static flag) and the -mfpu option is used for both compiling and linking. When linking, specifying -mfpu=vfp forces the static linker to set the ELF flags in the executable header to indicate that it uses VFP instructions. The dynamic linker will detect this at runtime and load the VFP enabled runtime libraries as well as any VFP specific third party libraries that may be installed. If a third party library does not require a special VFP version, perhaps because it doesn't actually use floating point operations, then it is not necessary to build or install one; if the dynamic linker does not find a VFP specific library, it will fall back to the soft float version.

##### 1.3.4.1. VFP - How to detect a VFP build

If you need to conditionally compile a piece of code depending on whether VFP is being used, then this can be achieved like this:

       #if defined(__VFP_FP__) && !defined(__SOFTFP__)
       /* Your code here for VFP */
       #else
       /* Your code here for soft float */
       #endif

##### 1.3.4.2. VFP - Modules/SCL

It is possible to use VFP when targeting the SharedCLibrary using the options:

      -mfpu=vfp -mfloat-abi=softfp

However, there are some caveats:

- It is the responsibility of the programmer to create and destroy the VFP context as required (Unixlib would normally do this for you when it is the target runtime library).
- The functions within the SharedCLibrary that take or return floating point values are disabled due to incompatibilities in the way that such values are passed.
- The printf family of functions will not produce correct results when passed floating point values.

  ##### 1.3.4.3. VFP - Third party libraries

  At build time, it is up to the programmer to ensure that the correct library (ie, VFP enabled) is referenced at link time via the -L and -l options. At runtime any VFP enabled versions should be installed in:

         !SharedLibs.lib.abi-2/0.vfp

  ##### 1.3.5. Profiling (experimental)

  Profiling is the art of determining where the CPU spends most of its time when running your program. To enable profiling, the option -pg is passed to GCC during compiling and linking. An example, collatz.c should help to make this clearer:

         *gcc -pg -o collatz collatz.c

  Now, whenever the program is run, it will be profiled and upon exiting will write a file named gmon/out to the currently selected directory. This is a machine-readable file and must be processed by a program called gprof before the results can be made sense of. The simplist way to do this is to pass the executable and the gmon/out file to gprof on the command line:

         *gprof collatz gmon/out >gprof-output

  Note that the output of the command is written to a file, as the output from gprof contains formfeed characters (ASCII char 12) which cause unwanted effects when printed directly to the screen. For an explanation of the gprof results, please see the gprof manual.

  Optimising code (that is, using the -O switch when compiling) can effect how the code is profiled, for example, functions can apparently disappear and fail to be listed in the profiling results. This is most likely due to GCC inlining the function so that it does not exist as a function is its own right but becomes embedded in another function. One way around this is to tell GCC not to inline such functions by using:

         __attribute__ ((noinline))

  when declaring them.

  It is possible to control manually what is and is not profiled by using the moncontrol function, which is declared in the system header file <sys/gmon.h>. The value passed as the single argument to moncontrol should be 0 to stop profiling and 1 to start profiling, for example, if you have a function a() which calls b(), but you don't want b() to be profiled, then it may look like this:

         void b(void)
         {
           ...
         }

         void a(void)
         {
           ...
           moncontrol(0);
           b();
           moncontrol(1);
           ...
         }

  ##### 1.3.5.1. Profiling - System requirements

  Profiling support requires at least an ARM 600 and RISC OS 4. As only HAL and OS calls are used, it should work on any version of RISC OS with a HAL. For a 26 bit OS, the HAL26 module written by Theo Markettos is required.

  Due to the low level nature of the profiling support, this feature is currently deemed experimental, as it is difficult to gauge how it will interact with other programs. It's therefore advisable to save any important work before using the profiler. You should not attempt to profile two programs at the same time, as this will almost certainly fail (a future version may infact take steps to prevent it).

  ##### 1.3.5.2. Profiling - Shared libraries

  Support for profiling shared libraries is not yet implemented (although we hope to add this in the future), however, this does not prevent the dynamically linked program from being profiled. You should remember though that any functions within shared libraries will not count towards the profile.

  ##### 1.3.5.3. Profiling - How it works

  Profiling in RISC OS GCCSDK involves two techniques; counting functions calls, recording the relationships between each of them and recording how much time is spent in each. Compiling with -pg has the effect of inserting a function call to mcount at the beginning of every function. mcount is provided by UnixLib (which therefore must be the runtime library), and is responsible for incrementing a count for the current function and recording its caller.

  When linking, the use of -pg causes GCC to link against gcrt1-riscos.o instead of crt1-riscos.o. This tells UnixLib that profiling has been enabled and that it should start the profiling hardware timer. The hardware timer is set to generate an interrupt one hundred times every second. Upon each interrupt, the program being profiled is stopped and a small (interrupt) routine is called with the address at which the program stopped passed to it. The interrupt routine increments a counter for this particular address and then returns control back to the point of the interruption and the program continues as if nothing happened. This is called statistical sampling. The counters for each sample point are 16 bits wide which means that each can count to 65535 before overflow occurs. If an overflow of any of the samples is detected, profiling is automatically disabled, however, the result file is still written.

  #### 1.4. Switches

  This is a list of the simpler, standard switches for GCC. Full details can be obtained from the GNU C/C++ manual. Please see below for the ARM specific switches since these have altered from the original GCC version.

  ##### 1.4.1. General switches

  The switches described below are useable with any GNU compiler.

  -c
    Compile and assemble the source to the object file
  -S
    Compile the source to assembler code
  -E
    Pre-process the source file
  -o <file>
    Put the resulting output into <file>
  -O
    Apply some optimizations to the output
  -O2
    Apply full optimization.
  -O3
    Full optimization and inline small functions as well.
  -static
    Use static instead of shared UnixLib runtime library. This switch is implicitly implied when the SharedCLibrary runtime library is used (by using -mlibscl or -mmodule switches).

  ##### 1.4.2. ARM specific switches

  The ARM specific switches are documented in GNU C/C++ manual, section "ARM Options". The most important ones are:

  -mpoke-function-name (default) / -mno-poke-function-name
    Place the name of the current function before the start of the function to allow the post mortem debugger to print a readable backtrace.

    Turning this switch on can increase code size by about 3.5% for C programs and as much as 10% for C++. However, it should be noted that the performance of the generated application will not be slower. It is useful to turn this switch on when developing applications as it can lead to a clear indication of where a program is failing when a backtrace is generated.

  -msoft-float (default for when UnixLib runtime library is used)
    Select soft-float routines to be used and generated when floating point operations are needed. Unless you have hardware FP support in your ARM processor, soft-float routines result in faster executables.
  -mhard-float (default when SharedCLibrary runtime library is used)
    Makes that floating point (FP) ARM instructions will be used in the generated code.
  -mfpu=vfp
    Causes VFP floating point instructions to be generated.

  The -msoft-float and -mhard-float switches are mutually exclusive.

  ##### 1.4.3. RISC OS specific switches

  -mthrowback / -mno-throwback (default)
    Send errors to a text editor capable of receiving 'throwbacks'. Error throwbacks will only occur when the DDEUtils module has previously been loaded.
  -munixlib (default)
    Builds and links source code against the UnixLib headers and library files. Note that when used, this needs to be specified during compiling and linking. This defines the preprocessor define __TARGET_UNIXLIB__.
  -mlibscl
    Builds and links source code against the SharedCLibrary headers and library files. Note that when used, this needs to be specified during compiling and linking. This defines the preprocessor define __TARGET_SCL__.

    Switch -mmodule will implicitly select -mlibscl as well.

  -mmodule
    Generates code suitable for a RISC OS module. This will implicitly select -mlibscl. This also defines the preprocessor define __TARGET_MODULE__.

  The -munixlib and -mlibscl switches are mutually exclusive.

  ##### 1.4.4. Obsolete or not implemented GCCSDK specific switches

  -mapcs-26 / -mapcs-32
    From GCCSDK 3.3.3 release onwards, APCS-32 became default and APCS-R deprecated. With the releases before you could select between those two ABI's using respectively the mutually exclusive -mapcs-32 and -mapcs-26 switches.

    From GCCSDK 4 onwards we don't have any APCS-R support and made the switches -mapcs-32 and -mapcs-26 obsolete.

  -mamu
    Generates the file !Depend which contains a list of all the source files that the produced object depends on. This is intended for use with Acorn's Make Utility (AMU), which edits the makefile to include these after the '# Dynamic Dependencies' line.

    The use of GNU make is preferred as it allows to write more expressive Makefiles and ensures a better compatibility with or require less differences than Makefiles for cross-compiling.

  -mclient-static-data-offset (default)
    Only relevant when compiling a RISC OS module (switch -mmodule set). This specifies to use the client static data offset (at sl-536) instead of the library static data offset (sl-540).

    The -mclient-static-data-offset and -mlibrary-static-data-offset switches are mutually exclusive.

  -mlibrary-static-data-offset
    Only relevant when compiling a RISC OS module (switch -mmodule set). This specifies to use the library static data offset (at sl-540) instead of the client static data offset (sl-536). This is only to be used in very rare cases.

    The -mclient-static-data-offset and -mlibrary-static-data-offset switches are mutually exclusive.

  #### 1.5. Binary configurations

  As an overview, the following configurations are possible with the native RISC OS release :

  - Softfloat with shared UnixLib as runtime library: default configuration.
  - Softfloat with static UnixLib as runtime library: use '-static' switch when linking.
  - VFP with shared UnixLib as runtime library: use '-mfpu=vfp' when compiling and linking.
  - VFP with static UnixLib as runtime library: use '-mfpu=vfp' when compiling use '-mfpu=vfp -static' switches when linking.
  - Hardfloat with SharedCLibrary as runtime library: use '-mlibscl' when compiling and '-mlibscl' when linking. When creating a RISC OS module you specify '-mmodule' instead for both compilation and linking.

  #### 1.6. Predefines

  This is a short list of the most interesting and useful predefines set:

  __arm__
    Always defined in the RISC OS port and can be used to make a difference between ARM specific vs non-ARM code.
  __riscos
  __riscos__
    Always defined in the RISC OS port and can be used to make a difference between RISC OS specific vs non-RISC OS code.
  __ELF__
    Always defined as GCCSDK 4 is now ELF based.
  __SOFTFP__
    Defined when soft-float routines are used in the to be generated code in contrast with using floating point (FP) instructions. FP instructions will be used when the SharedCLibrary runtime library is selected (switch -mlibscl and/or -mmodule is selected). When UnixLib runtime library is used, by default soft-float routines are used unless you have -mhard-float or -mfpu=vfp specified.
  __VFP_FP__
    Defined when the floating point format in use is that of the ARM VFP unit, which is native-endian IEEE-754
  __TARGET_SCL__
    Defined when targeting the SharedCLibrary runtime library, i.e. when -mlibscl or -mmodule switches are supplied.
  __TARGET_MODULE__
    Defined when module code is being generated, i.e. when -mmodule switch is supplied.
  __TARGET_UNIXLIB__
    Defined when targeting the UnixLib runtime library, i.e. when -mlibscl nor -mmodule switches are supplied (as -munixlib is default switch).

  GCCSDK 3 defines the predefine __aof__ which is no longer the case in GCCSDK 4 as it is now fully ELF based. So this can be used to distinguish between AOF and ELF compilations.

  GCCSDK 3 also defines __arm (together with __arm__) while GCCSDK 4 only defines __arm__.

  More common predefines are documented in the section "Common Predefined Macros" of the GNU C preprocessor manual.

  Note that these predefines can also be used in handwritten assembler code when making sure that the preprocessor is firstly invoked before the assembling faze:

         *gcc -xassembler-with-cpp -o file.o -c file.s

  with e.g. file.s:

      	@ Returns 1 when running with UnixLib, 0 when running with SharedCLibrary.
      	.global	using_unixlib
      	.type	using_unixlib, %function
      using_unixlib:
      #ifdef __TARGET_UNIXLIB__
      	MOV	r0, #1
      #else
      	MOV	r0, #0
      #endif
      	MOV	pc, r14
      	.size	using_unixlib, . - using_unixlib

  #### 1.7. Migrating projects to GCCSDK 4

  The GCCSDK 4 release contains a significant number of changes compared to its previous stable GCCSDK 3.4.6 release and this might require some changes to your project when you want to build it with GCCSDK 4.

  - Object format is ELF

    Pre GCCSDK 4 releases had as object format AOF (Acorn Object Format) and the AOF based libraries came as ALF (Acorn Library Format). RISC OS Absolute programs (filetype &FF8) came in an AIF file format (Acorn Image Format).

    As those formats are not supported by GNU binutils' assembler 'gas' nor linker 'ld', this means that your projects needs to be completely rebuilt as you can not use previously made (or supplied) AOF/ALF files. In case of C or C++ files this is most probably just a case of recompiling. In case of assembler files, the sources need to be changes to make them 'gas' compatible (read further on). In case of creating library, the process can be slightly different (read further on).

    Both object files, shared library files and resulting fully linked binary files are in ELF file format (filetype &E1F). There is no native RISC OS support for loading shared libraries and ELF linked binary files so that's why you need an ELF loader such like 'SOManager' (currently part of !SharedLibs application).

    There are two ways to create AIF based program files which of course do not need the use of 'SOManager' to run those programs:

    - Use elf2aif program to convert an ELF binary not using any shared library into AIF. This means you need to specify '-static' linker switch when making ELF binary.
    - Use the SharedCLibrary instead of UnixLib as runtime library, i.e. use '-mlibscl' during compilation and linking. In this case the linker will automatically create an AIF application program so no explicit elf2aif invocation is needed.

    Aside: when creating a module (i.e. using '-mmodule' during compilation and linking), the intermediate object files are ELF based but the final binary produced by the linker is a valid RISC OS module which of course does not need the 'SOManager' ELF loader.

  - Assembler code

    As the object format is ELF you need to make use of an assembler outputting ELF. There are two options:

    - You use asasm (previously known as 'as' which was originally written by Niklas Röjemo). 'asasm' is designed to be Acorn objasm compatible and will by default output ELF object format.
    - You use GNU assembler as but this means that your assembler code needs to be tuned for 'gas' assembler syntax.
  - 'gas' assembler syntax

    The syntax used for 'gas' is slightly different and the most important differences are:

    - Labels : 'as' assembler labels start at the beginning of a line can be optionally be pre- and postfixed with a '|' character like "mylabel" or "|mylabel|". 'gas' does not support the optional '|' character and requires that a label gets terminated with a column ':'.

      So, 'as' assembler code like:

          |mylabel1|
          	ADD	r0, r0, #1
          mylabel2
          	MOV	pc, r14

      needs to be changed to:

          mylabel1:
          	ADD	r0, r0, #1
          mylabel2:
          	MOV	pc, r14

    - Comments : 'as' assembler used semi-column ';' to mark the start of a comment line. 'gas' syntax is using the '@' character. You can also use the C style comments "/* ... */" if you enable preprocessing before assembling your code (use filename.S instead of filename.s)
    - IMPORT : the IMPORT statement followed by a symbol name is no longer needed unless you want to import a symbol 'weakly'.

          	IMPORT	|mylabel1|
          	IMPORT	|mylabel2|, WEAK

      needs to be changed to:

          	.weak	mylabel2

    - Variable setting:

          abc	* 0
          def	* &1234

      needs to be changed to:

          .set abc, 0
          .set def, 0x1234

      Or:

          abc	EQU 0
          def	EQU &1234

      needs to be changed to:

          #define	abc	0
          #define	def	0x1234

      and you assemble the code using:

          gcc -xassembler-with-cpp -o file.o -c file.s

      so that the pre-processor can expand the #define definitions.
    - Space claiming:

          	% 256

      needs to be changed to:

          	.space 256

      Or:

          	^	0, ip
          parentprogname	#	4	; Ptr to program name
          editname	#	12	; Edit name
          WSSize		*       :INDEX:

          	LDR	r0, parentprogname
          	ADR	r2, editname
          	MOV	r3, #WSSize

      needs to be changed to:

                  .struct	0
          parentprogname	: .skip   4	@ Ptr to program name
          editname	: .skip   12	@ Edit name
          WSSize		:

          	LDR	r0, [ip, #parentprogname]
          	ADD	r2, ip, #editname
          	MOV	r3, #WSSize

    - Constant notation:

          	TEQ	r1, #"R"

      needs to be changed to:

          	TEQ	r1, #'R'

      Integer notation:

          	TST	r0, #2_0101	; Binary value
          	TEQ	r0, #8_12	; Octal value
          	TEQ	r0, #&100	; Hex value

      needs to be changed to:

          	TST	r0, #0b0101	@ Binary value (or 0B0101 can be used)
          	TEQ	r0, #012	@ Octal value, notice the extra digit 0 as first character
          	TEQ	r0, #0x100	@ Hex value (or 0X100 can be used)

    - EXPORT : the EXPORT statement is to be replaced by '.global'.

          	EXPORT	|mylabel|

      needs to be changed to:

          	.global	mylabel

    - Other directives:

          	AREA	bla_data, DATA
          	AREA	bla_data_noinit, DATA, NOINIT
          	AREA	bla_code, CODE
          	DCB	&12
          	DCD	&12345678
          	=	"test"
          	=	" and another test", 0
          	END

      needs to be changed to:

          	.data	@ A short form of .section + arguments
          	.bss
          	.text	@ A short form of .section + arguments
          	.byte	0x12
          	.word	0x12345678
          	.ascii	"test"
          	.asciz	" and another test"
          	.end	@ ".end" can be left out and is not required.

    - Macros are quite different and there are no mechanical easy rules for translation. Refer to GNU assembler as for full description on '.macro' and '.mend'.

    More information can be found in GNU assembler as and in this GNU ARM Assembler Quick Reference.

  - Specifying how to link with libraries : the 'drlink' linker used in pre-GCCSDK 4 releases was quite liberal dealing with object and library files and didn't need any special handling to make a difference between those two file formats so in pre-GCCSDK 4 projects you could see link lines like:

        *gcc -o myapp object1.o object2.o OSLib:o.OSLib32

    which links the object1.o and object2.o object files with the RISC OS OSLib library found as OSLib:o.OSLib32. The binutils' linker needs to have its libraries specified with '-l' switch and further assumes that all libraries filenames on disc start with 'lib' (but omitted when specified) and have an 'a' extension instead of 'o' which was usually used in pre-GCCSDK 4 projects. Also it is preferred to specify the directory where the library can be found using an extra switch '-L' (in fact, this specifies an additional search directory for the '-l' libraries). So above example needs to be changed for GCCSDK 4 as:

        *gcc -o myapp object1.o object2.o -LOSLib: -lOSLib32

    and this with the file "libOSLib32/a" stored in the directory defined by the 'OSLib:' path. Note we don't do suffix swapping for 'a' extensions. Of course, it is expected that ELF releases of libraries already have the 'lib' prefix and '/a' extension of the library filename.

  - APCS-R / APCS-32 : when switch '-mapcs-32' is used, you have to remove this from the command line as this is default now and there isn't any APCS-R support foreseen. When your project is still APCS-R, you need to drag it into the 21st century and make it APCS-32 compliant. When you don't have any assembler code in your project, this is just a matter of recompiling your project.
  - Softfloat & hardfloat: the default configuration is now softfloat which means that there is no use of floating point instructions which are most of times emulated with a significant overhead. The floating point implementation is done using built-in library support not requiring the FPEmulator module in RISC OS.

    This change has hardly any effect on your project when you migrate to GCCSDK 4 except for the improved runtime speed for floating point intensive code.

  #### 1.8. Distributing your programs

  When you want to distribute your compiled program it might be necessary to accompany it with an ELF loader and possibly also a set of shared libraries used by your program. This is not necessary when your program is a static ELF binary which has been converted with elf2aif or when it is using SharedCLibrary as runtime library (as for both cases your program is an Absolute (filetype &FF8) file with AIF header) or when it is a RISC OS module (filetype &FFA).

  The ELF loader and the default set of shared libraries (UnixLib, libgcc and the dynamic loader) are bundled in the form of the !SharedLibs application. In the download section of the GCC page there is separate 'core' !SharedLibs ZIP file available which can be downloaded by the users of your program. You will also need the C support and possibly also the C++ support additions.

  We strongly recommend that you instruct your users to download !SharedLibs ZIP file(s) themselves instead of providing a copy of a possibly outdated version together with your program.

  #### 1.9. Troubleshooting

  Here are described some common problems users have with gcc and the GNU compilers. Possible solutions are provided for the known problems.

  - Double clicking on !GCC filer icon results in an error "There are still SharedUnixLibrary clients active".

    GCCSDK 4 requires at least SharedUnixLibrary version 1.12. This error is because you have a version loaded in memory which is prior to that version and still currently in use by one or more UnixLib compiled programs.

    Loading a newer version of the SharedUnixLibrary is not possible until all those UnixLib compiled programs have been stopped.

    You should quit all those UnixLib compiled programs and again double click on !GCC filer icon.

  - Double clicking on !GCC filer icon results in an error "GCCSDK 4 requires SharedUnixLibrary 1.12 or later".

    You have no or a not up-to-date version of the SharedUnixLibrary module in your !System. Use the GCCSDK supplied !System and use the System merge utility provided by Configure to merge this with your !System.

  - The compiler fails to compile anything but no error message is reported.

    This is usually caused by a lack of memory. To see how far through compilation a file has gone, try compiling with the '-v' switch. '-v' gives verbose output and will show the programs gcc is executing.

    A lack of memory will be shown up by an almost instantaneous return from any program executed. If this happens, try increasing the wimpslot, using *wimpslot -min 15000K.

    When the compiler runs out of memory during compilation, an error 'virtual memory exhausted' is usually reported.

  - The error 'No writable memory at this address' is returned.

    This is caused by insufficient memory memory and can be fixed by increasing the wimpslot to similar values as above.

  ### 2. UnixLib

  #### 2.1. Locales

  Standard locale names in the form language-territory[.codeset], where language is an ISO 639 language code and territory is an ISO 3166 country code, are recognised and returned by setlocale. For example, the United Kingdom is "en-GB". The codeset is ignored, but accepted. The following table lists the locales that are recognised and the corresponding RISC OS territory:

  RISC OS Territory | Locale name
  --- | ---
  UK | en-GB
  Germany | de-DE
  France | fr-FR
  Netherlands | nl-NL
  Italy | it-IT
  Spain | es-ES
  Portugal | pt-PT
  Greece | el-GR
  Sweden | sv-SE
  Finland | fi-FI
  Denmark | da-DK
  Norway | no-NO
  Iceland | is-IS
  Canada | en-CA
  Turkey | tr-TR
  Arabic | ar-SA
  Ireland | en-IE
  Hong Kong | zh-HK
  Russia | ru-RU
  Israel | he-IL
  Mexico | es-MX
  Australia | en-AU
  Austria | de-AT
  Belgium | nl-BE
  Japan | ja-JP
  Switzerland | de-CH
  USA | en-US
  China | zh-CN
  Brazil | pt-BR
  SAfrica | af-ZA
  Korea | ko-KR
  Taiwan | zh-TW
  Faroe | fo-FO
  Albania | sq-AL
  Bulgaria | bg-BG
  Czech | cs-CZ
  Farsi | fa-IR
  Gujarati | gu-IN
  Estonia | et-EE
  Hungary | hu-HU
  Latvia | lv-LV
  Lithuania | lt-LT
  Macedonia | mk-MK
  Poland | pl-PL
  Punjabi | pa-IN
  Romania | ro-RO
  Slovak | sk-SK
  Slovene | sl-SL
  Tamil | ta-IN
  Ukraine | uk-UA
  Swiss1 | fr-CH
  Swiss2 | de-CH
  Swiss3 | it-CH

  The special locales "C" and the equivalent "POSIX" are also recognised, but obviously have no corresponding territory name.

  #### 2.2. Shared library compatibility

  Sometimes it's necessary to make changes to UnixLib or the way it is compiled that make it incompatible with previous versions of the compiler or programs built with a previous compiler version. For programs that are statically linked this is not a problem as all the code required to run the program is packaged up inside the program itself. However, with dynamic linking problems can arise when trying to run a program built with an older version of the compiler using a newer version of the UnixLib shared library (and other runtime libraries).

  To overcome this, we use ABI (Application Binary Interface) versioning. The compiler embeds the current version of the ABI, as a string, into any libraries or programs that it builds. This string is used by the dynamic linker to identify the sub directory within "!SharedLibs.lib" from which to load the correct libraries.

  If a change is made in UnixLib or the way it's built that would make it incompatible with previous versions, then we increase the version number of the ABI. This allows different versions of the standard libraries (or in fact any library) to exist at the same time, and the dynamic linker will select the correct one a runtime.

  The currently known ABI versions are:

- abi-0.0
  This corresponds to V4.1.1 of GCC. As the ABI system was introduced sometime after the release of this version of the compiler, it was not possible to "retro-fit" ABI versioning, so GCC 4.1.1 is only notionally ABI-0.0. Its libraries are stored in "!SharedLibs.lib" directly rather than in an ABI directory.
- abi-1.0
  This corresponds to V4.1.2 of GCC. This is the first version of GCC that supports the ABI versioning system. Its libraries are stored in "!SharedLibs.lib.abi-1/0".
- abi-2.0
  This is the current ABI version and corresponds to V4.6 and onwards of GCC. Its libraries are stored in "!SharedLibs.lib.abi-2/0".

  ### 3. Known issues or unsupported GCCSDK 3.4.6 features

  List of known problems or missing features compared to GCCSDK 3.4.6:

  - native RISC OS build: not all RISC OS specific switches are implemented yet, like -mamu, -mlibrary-static-data-offset, -mclient-static-data-offset.

  ### 4. Changes

  GCCSDK 4 produces ELF object files, libraries and binaries while in GCCSDK 3 this was AOF/AIF based. Currently there is no support to mix AOF object or library files with ELF object files.

  For each GCCSDK release an overview of the most important changes are made in its Changes file.

  More details on the changes made in particular areas can be found in:

  - UnixLib ChangeLog
  - SharedCLibrary ChangeLog
  - asasm ChangeLog
  - CMunge official history and its specific GCCSDK changes which haven't made in an official release yet.
  - elf2aif ChangeLog
  - mkresfs ChangeLog

  ### 5. Further documentation

  GNU GCC/binutils documentation:

  - GNU C/C++ compiler
  - GNU C preprocessor
  - GNU assembler as
  - GNU linker ld
  - GNU Binary Utilities: a large set of utilities for creating, inspecting and modifying binary object files.
  - GNU libiberty: a collection of subroutines used by various GNU programs. It is available under the Library General Public License.

  Runtime documentation:

  - UnixLib: the default runtime library used when compiling programs with GCC. The UnixLib's intend is to provide, as much as possible, a fully POSIX-compatible runtime library for RISC OS in order to compile and run most (but not all) POSIX-compatible code that avoids OS specific code.
  - SharedCLibrary: this is an alternative runtime library which is using the SharedCLibrary RISC OS module. It has the advantage that those applications are usually smaller in size but does not have a rich API as UnixLib. When building modules, this is the only runtime library you can use.

  Shared library support on RISC OS:

  - RISC OS shared library documentation for the developer.
  - Advanced RISC OS shared library documentation (for GCCSDK developers).

  RISC OS related documentation:

  - asasm: an Acorn objasm clone outputting AOF and ELF files and previously known as 'as' and originally written by Niklas Röjemo. This also contains the AIF, ALF, AOF, APCS and ASDTF specifications.
  - CMunge: a tool to generates a suitable veneer to allow RISC OS modules to be developed in C or C++.
  - elf2aif: a tool to convert static ELF binaries into AIF Absolute files avoiding the need for ELF loader at runtime.
  - ln: a tool to create symlink files for use with the dynamic linking GCC, although they can be used with any UnixLib compiled program.
  - mkresfs: a tool to generate C code that creates and removes files from ResourceFS in your RISC OS modules.

  ### 6. GCCSDK website, bug reporting & mailing list

  The GCCSDK website contains more information like how you can log bugs, addressing the GCCSDK development itself and related RISC OS development aspects. Currently the GCCSDK website is Wiki based so your input in the form of changes and/or additional input is greatly appreciated.

  Most importantly, you can also find details how you can join the GCCSDK mailing which has been setup for discussions on GCCSDK, including its development work. We strongly recommend to join this mailing list.

  ### 7. Licenses and warranty

  This port of GCC is:

      Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 Nick Burrett
      Copyright (c) 2002-2015 GCCSDK Developers

  The GCCSDK releases made by the GCCSDK Developers consists of several binaries and sources which do not necessary have the same licenses. The following overview can help to identify those licenses more easily but is in no way an authoritative statement on behalf of the GCCSDK Developers:

  - binutils (and all its associated files) : See its manual.
  - asasm : See !GCC.docs.asasm.COPYING.
  - cmunge : See !GCC.docs.cmunge.Copyright.
  - elf2aif : See !GCC.docs.elf2aif.COPYING.
  - gcc (and all its associated files) : See its manual.
  - ln : See !GCC.docs.ln.COPYING.
  - mkresfs : See !GCC.docs.mkresfs.COPYING.
  - SharedCLibrary (aka libscl) : See !GCC.docs.SharedCLibrary.COPYING.
  - UnixLib : See !GCC.docs.libunixlib.COPYING.

  As with all GNU programs, THERE IS NO WARRANTY OF ANY SORT.

  ### 8. Credits

  Primary GCCSDK Developers today are:

  - Lee Noar - Shared library development including ELF loader.
  - Theo Markettos - build system and release management

  An enormous amount of porting and testing work was done by Nick Burrett. Without his past contribution GCCSDK wouldn't exist.

  The following people have also made contributions over the last years (in alphabetic order) :

  Ben Avison, John-Mark Bell, Stefan Bellon, Alan Buckley, James Bursa, Steve Ellacott, Chris Gransden, Rich Hudson, Rob Kendrick, Jeffrey Lee, Adrian Lees, Christian Ludlam, Duncan Moore, Peter Naulls, Alex Macfarlane Smith, Theo Markettos, David Marston, Philip Pemberton, Graham Shaw, Tony van der Hoff, Alex Waugh, Simon Wilson, Martin Wuerthner.

  Special thanks to the following people having written programs which are used in the GCCSDK project :

  - Justin Fletcher and Robin Watts for 'CMunge', a free alternative to CMHG.
  - Rob Kendrick for his 'mkresgen', a C code generator to add/remove files to/from ResourceFS.
  - All UnixLib Developers for providing a run-time library which is essential for GCCSDK and ported programs using GCCSDK.

  Thanks also to all the testers and bug reporters.

  And last but not least, all the GCC and binutils contributors.